LeetCode算法

LeetCode 回溯与剪枝

导读:最近做了几道LeetCode的回溯问题,有点体会,在此记录防止遗忘。

LeetCode 回溯与剪枝回溯问题概要46题 全排列47题 全排列II39题 组合总和40题 组合总和II

回溯问题概要

  1. 画出决策树
  2. 分析剪枝策略,避免重复解
  3. 使用DFS递归算法,写出代码并debug

要点:进入新一层递归刷新状态,递归退出时状态恢复

46题 全排列

描述:此题给出了一个不含重复元素的数组,要求输出该数组的所有字典序全排列。

分析:以 [1,2,3] 为例,画出决策树如下:

empty
1
2
3
1
2
3
1
2
3
1
2
3
1
3
3
2
2
1

其中,虚线 部分表示剪枝操作,第三层递归的剪枝省略。

Java代码:

47题 全排列II

描述: 此题与上一题的区别在于给出的数组含有重复元素,仍要求给出字典序全排列。

分析:除了保留上一题的剪枝方法,由于重复元素的使用会导致结果集重复(例如 [1,1,2],如果按原有剪枝策略,第二个1仍会被记录到 tmpli 中),因此要修改剪枝策略。

Java代码:

39题 组合总和

描述: 给出一个数组和目标值,要求给出数组中总和为目标值的所有组合,元素可以重复使用。

分析:尝试逐级递减,递归出口条件为减少至0或为负数。为了不产生重复的结果集,先对数组排序,且每次选取的元素不能超过上一次选取的值。

Java代码:

40题 组合总和II

描述:与上一题类似,但不允许使用重复的值(数组中会给出多个重复值,每个值只能用一次,如[1,1,2])。

分析:大致与上一题类似,但每一层不允许使用重复元素,可以参考47题的剪枝,但又为了防止重复解,其剪枝方式有点不同。

Java代码: